package com.cloudsdo.cameratest.model;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import com.arcsoft.face.ErrorInfo;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceInfo;
import com.cloudsdo.cameratest.core.BitmapUtil;
import com.cloudsdo.cameratest.core.FaceUtil;
import com.cloudsdo.cameratest.dao.Student;
import com.cloudsdo.cameratest.dao.StudentDao;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * -----------------------------------------------------------------
 * Copyright (C) 2014-2016, by your company, All rights reserved.
 * -----------------------------------------------------------------
 * File: Stident.java
 * Author: win7
 * Version: V100R001C01
 * Create: 2019/8/6 13:48
 * Changes (from 2019/8/6)
 * -----------------------------------------------------------------
 * 2019/8/6 : Create Stident.java (win7);
 * -----------------------------------------------------------------
 */
public class StuData {
    private static final String TAG = "StuData";
    private List<FaceFeature> faceFeatureList=new ArrayList<>();
    private HashMap<FaceFeature,Student> studentFaceFeatureHashMap=new HashMap<>();
    private static String facePath= Environment.getExternalStorageDirectory().getAbsolutePath()+"/face";
    private static StuData stuData;
    private Context context;
    private FaceEngine faceEngine;
    public StuData(Context context) {
        this.context=context;
    }

    public StuData setFaceEngine(FaceEngine faceEngine) {
        this.faceEngine = faceEngine;
        return this;
    }

    public synchronized static StuData getInstance(Context context) {
        if (stuData == null) {
            synchronized (StuData.class){
                if(stuData==null){
                    stuData = new StuData(context);
                }
            }
        }
        return stuData;
    }

    public List<FaceFeature> getFaceFeatureList() {
        return faceFeatureList;
    }

    public HashMap<FaceFeature, Student> getStudentFaceFeatureHashMap() {
        return studentFaceFeatureHashMap;
    }




    public void loadFeature(){
        File file=new File(facePath);
        if(file.exists()){
            File[] files=file.listFiles();
            for(int i=0;i<files.length;i++){
                Log.e(TAG,"文件列表:"+files[i].getName());
                FaceFeature faceFeature=new FaceFeature();
                try {
                    FileInputStream inputStream = new FileInputStream(files[i]);
                    byte[] buffer = new byte[(int) files[i].length()];
                    inputStream.read(buffer);
                    faceFeature.setFeatureData(buffer);
                    StuData.getInstance(context).getFaceFeatureList().add(faceFeature);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }else{
            file.mkdirs();
        }
    }

    public void loadFeatureFromImage(){
        File file=new File(facePath);
        if(file.exists()){
            File[] files=file.listFiles();
            for(int i=0;i<files.length;i++){
                Log.e(TAG,"文件列表:"+files[i].getName());
                FaceFeature faceFeature=new FaceFeature();
                try {
                    FileInputStream inputStream = new FileInputStream(files[i]);
                    byte[] buffer = new byte[(int) files[i].length()];
                    inputStream.read(buffer);
                    faceFeature.setFeatureData(buffer);
                    StuData.getInstance(context).getFaceFeatureList().add(faceFeature);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }else{
            file.mkdirs();
        }
    }

    public void loadFeatureFromDB(){
        clear();
        StudentDao studentDao=new StudentDao(context,Student.class);
        List<Student> list=studentDao.queryAll();
        for(int i=0;i<list.size();i++){
            Student student=list.get(i);
            if(student.getImg().isEmpty()){
                return;
            }
            boolean ok=handlerStu(student);

            if(!ok){
                loadFeatureFromDB();
            }
        }

        Log.e(TAG,"list size=" +list.size());
    }

    public boolean handlerStu(Student student) {
        boolean ok=false;
        try {
            List<FaceInfo> faceInfoList = new ArrayList<>();
            Bitmap bitmap= BitmapFactory.decodeFile(student.getImg(), BitmapUtil.getBitmapOption(2));
            int width=bitmap.getWidth();
            int height=bitmap.getHeight();
            byte[] nv21=BitmapUtil.bitmapToNv21(bitmap,width, height);
            int code = faceEngine.detectFaces(nv21, width, height, FaceEngine.CP_PAF_NV21, faceInfoList);
            if (code == ErrorInfo.MOK && faceInfoList.size() >0) {
                //人脸检测成功并且检测到了人脸的情况
                FaceUtil.keepMaxFace(faceInfoList);
                FaceFeature faceFeature = new FaceFeature();
                int featureCode = faceEngine.extractFaceFeature(nv21, width, height, FaceEngine.CP_PAF_NV21, faceInfoList.get(0), faceFeature);
                Log.e(TAG,"featureCode="+featureCode);
                if(!StuData.getInstance(context).getStudentFaceFeatureHashMap().containsKey(faceFeature)){
                    StuData.getInstance(context).getStudentFaceFeatureHashMap().put(faceFeature,student);
                    StuData.getInstance(context).getFaceFeatureList().add(faceFeature);
                }
                if (featureCode == ErrorInfo.MOK) {
                    ok=true;
                    //特征提取成功

                }else{
                    //特征提取失败，可根据code查看原因
                }
            }else{
                //人脸检测失败或未检测到人脸的情况
                Log.e(TAG,"faceInfoList is empty");
                if(faceInfoList.isEmpty())ok=true;
            }
            bitmap.recycle();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ok;
    }

    public void clear() {
        faceFeatureList.clear();
        studentFaceFeatureHashMap.clear();
    }
}
